use poem::{listener::{ TcpListener}, Route, Server};
use poem_openapi::{payload::{PlainText,Binary},OpenApi, OpenApiService,ApiResponse };
use std::env;

use simple_excel_writer::*;
use uuid::Uuid;
use std::io::Read;

use urlencoding::encode;

struct CommonApi;

#[OpenApi]
impl CommonApi {
    #[oai(path = "/health", method = "get")]
    async fn health(&self)-> PlainText<&'static str> {
        PlainText("ok")
    }
}


#[derive(Debug, ApiResponse)]
enum GetFileResponse {
    #[oai(status = 200)]
    Ok(
        Binary<Vec<u8>>,
        #[oai(header = "Content-Disposition")] String,
        #[oai(header = "Content-Type")] String,
    ),
    /// File not found
    #[oai(status = 404)]
    NotFound,
}



struct ExportApi;

#[OpenApi]
impl ExportApi {
    #[oai(path = "/exportexcel", method = "post")]
    async fn exportexcel(&self) -> GetFileResponse  {


        match std::fs::create_dir("/tmp") {
            Err(why) => println!("! {:?}", why.kind()),
            Ok(_) => {},
        }
        let filename:String =format!("/tmp/{}.xlsx",Uuid::new_v4() ) ;
        let mut wb = Workbook::create(&filename);
        let mut sheet = wb.create_sheet("第一页");
    
        // set column width
        sheet.add_column(Column { width: 30.0 });
        sheet.add_column(Column { width: 30.0 });
        sheet.add_column(Column { width: 80.0 });
        sheet.add_column(Column { width: 60.0 });
    
        wb.write_sheet(&mut sheet, |sheet_writer| {
            let sw = sheet_writer;
            sw.append_row(row!["Name", "Title","Success","XML Remark"])?;
            sw.append_row(row!["Amy", (), true,"<xml><tag>\"Hello\" & 'World'</tag></xml>"])?;
            sw.append_blank_rows(2);
            sw.append_row(row!["Tony", blank!(2), "retired"])
        }).expect("write excel error!");
    
        let mut sheet = wb.create_sheet("第二页");
        wb.write_sheet(&mut sheet, |sheet_writer| {
            let sw = sheet_writer;
            sw.append_row(row!["Name", "Title","Success","Remark"])?;
            sw.append_row(row!["Amy", "Manager", true])
        }).expect("write excel error!");
    
        
        wb.close().expect("close excel error!");

        let file_name =encode(&"导出excel.xlsx".to_owned());
        let content_disposition =format!("attachment;filename* = UTF-8''{}", file_name);


        let mut data = Vec::new();
        let mut file = std::fs::File::open(filename).unwrap();
        file.read_to_end(&mut data).unwrap();

        let content_type =String::from("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

        GetFileResponse::Ok(Binary(data.clone()), content_disposition,content_type)
    }

}


#[tokio::main]
async fn main() -> Result<(), std::io::Error> {
    if std::env::var_os("RUST_LOG").is_none() {
        std::env::set_var("RUST_LOG", "poem=debug");
    }
    tracing_subscriber::fmt::init();



    

    let output_domain =env::var("OUTPUT_DOMAIN").unwrap();

    let api_service = OpenApiService::new((CommonApi,ExportApi), "poem export excel demo", "1.0")
        .server(format!("http://{}/api",&output_domain));
    let ui = api_service.swagger_ui();

    let listener =
        TcpListener::bind("0.0.0.0:17878");

    Server::new(listener)
        .run(Route::new().nest("/api", api_service).nest("/", ui))
        .await
}